/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.pa165.languageschoolservice.serviceImpl;

import com.pa165.languageschoolpersistence.DAO.LectorDAO;
import com.pa165.languageschoolpersistence.DAO.LectureDAO;
import com.pa165.languageschoolpersistence.Exceptions.IllegalArgumentPersistenceException;
import com.pa165.languageschoolpersistence.Exceptions.ServiceFailureException;
import com.pa165.languageschoolpersistence.entities.Lector;
import com.pa165.languageschoolpersistence.entities.Lecture;
import com.pa165.languageschoolservice.DTO.LectorDTO;
import com.pa165.languageschoolservice.DTO.LectureDTO;
import com.pa165.languageschoolservice.service.LectorService;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Elena Medvedeva
 */
@Service("lectorService")
public class LectorServiceImpl implements LectorService {

    @Resource(name = "lectorDAO")
    private LectorDAO lectorDAO;
    @Resource(name = "lectureDAO")
    private LectureDAO lectureDAO;
    @Autowired
    private Mapper mapper;

    public void setLectureDAO(LectureDAO lectureDAO) {
        this.lectureDAO = lectureDAO;
    }

    public Mapper getMapper() {
        return mapper;
    }

    public void setMapper(Mapper mapper) {
        this.mapper = mapper;
    }

    public LectorDAO getLectorDAO() {
        return lectorDAO;
    }

    public void setLectorDAO(LectorDAO lectorDAO) {
        this.lectorDAO = lectorDAO;
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public LectorDTO get(Long id) throws  IllegalArgumentPersistenceException{
        if (id == null) {
            throw new IllegalArgumentException("Id is null LectorServiceImpl.get");
        }
        Lector lector = lectorDAO.get(id);
        LectorDTO lectorDTO = null;
        if (lector != null) {
            lectorDTO = mapper.map(lector, LectorDTO.class);
        }
        return lectorDTO;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public LectorDTO add(@Valid LectorDTO lectorDTO) throws ServiceFailureException {
        if (lectorDTO == null) {
            throw new IllegalArgumentException("lectorDTO is null in  LectorServiceImpl.add ");
        }
        Lector lector = mapper.map(lectorDTO, Lector.class);
        lectorDAO.add(lector);
        return mapper.map(lector, LectorDTO.class);
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void remove(@Valid LectorDTO lectorDTO) throws  IllegalArgumentPersistenceException{
        if (lectorDTO == null) {
            throw new IllegalArgumentException("lectorDTO is null in  LectorServiceImpl.remove ");
        }
        if (lectorDTO.getId() == null) {
            throw new IllegalArgumentException("lectorDTO.Id is null in LectorServiceImpl.remove ");
        }
        Lector lector = mapper.map(lectorDTO, Lector.class);
        lectorDAO.remove(lector);
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public LectorDTO modify(@Valid LectorDTO lectorDTO) throws  IllegalArgumentPersistenceException{
        if (lectorDTO == null) {
            throw new IllegalArgumentException("lectorDTO is null in  LectorServiceImpl.modify ");
        }
        if (lectorDTO.getId() == null) {
            throw new IllegalArgumentException("lectorDTO.Id is null in LectorServiceImpl.modify ");
        }
        Lector lector = mapper.map(lectorDTO, Lector.class);
        lectorDAO.modify(lector);
        return mapper.map(lector, LectorDTO.class);
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public List<LectorDTO> getAll() {
        List<Lector> lectors = lectorDAO.getAll();
        List<LectorDTO> result = new ArrayList<LectorDTO>();
        for (Lector lector : lectors) {
            result.add(mapper.map(lector, LectorDTO.class));
        }
        return result;
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public List<LectorDTO> findByName(String name) throws  IllegalArgumentPersistenceException {
        if (name == null) {
            throw new IllegalArgumentException("name is null in LectorServiceImpl.findByName ");
        }
        List<Lector> lectors = lectorDAO.findByName(name);
        List<LectorDTO> result = new ArrayList<LectorDTO>();
        for (Lector lector : lectors) {
            result.add(mapper.map(lector, LectorDTO.class));
        }
        return result;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public LectureDTO enrollLecture(@Valid LectureDTO lectureDTO, @Valid LectorDTO lectorDTO) throws ServiceFailureException {
        if (lectureDTO == null || lectureDTO.getId() == null) {
            throw new IllegalArgumentException("lectureDTO or lectureDTO.id is null in LectorServiceImpl.enrollLecture ");
        }
        if (lectorDTO == null || lectorDTO.getId() == null) {
            throw new IllegalArgumentException("lectorDTO or lectorDTO.id is null in LectorServiceImpl.enrollLecture ");
        }
        if ((lectorDAO.get(lectorDTO.getId()) == null) || (lectureDAO.get(lectureDTO.getId()) == null)) {
            throw new ServiceFailureException("from LectorServiceImpl.enrollLecture: lector or lecture are not in the DB ");
        }
        Lecture lectureToEnroll = lectureDAO.get(lectureDTO.getId());
        Lecture lecture = lectorDAO.enrollLecture(lectureToEnroll, mapper.map(lectorDTO, Lector.class));

        return mapper.map(lecture, LectureDTO.class);

    }
}
